#include "cbuilder.h"
#include <d3d11.h>
#include <d3dx11.h>
#include "../direct3d/d3dstructs.h"

namespace NEngine {

// ================================================================================================
// Build lights in the scene
// ================================================================================================
void CBuildLights::BuildLights(CImportLights::SLightObj& lobjects, 
                               CDynamicArray<CCamera>& cams, CDynamicArray<CCamera*>& lviews) {
    uint numdirlights;
    uint numptlights;

    // -- make sure we don't have more dir lights than supported
    if(lobjects.numdirlights > MAX_LIGHTS) {
        ASSERT_(0, "More directional lights than supported");
        numdirlights = MAX_LIGHTS;
    }
    else 
        numdirlights = lobjects.numdirlights;

    // -- make sure we don't have more point lights than supported
    if(lobjects.numptlights > MAX_LIGHTS) {
        ASSERT_(0, "More point lights than supported");
        numptlights = MAX_LIGHTS;
    }
    else
        numptlights = lobjects.numptlights;

    // -- make sure we dont' have more spt lights than supported
    if(lobjects.numsptlights > kMaxConeLights) {
        ASSERT_(0, "More spot lights than supported");
        lobjects.numsptlights = kMaxConeLights;
    }

    // -- create data for constant buffer dir lights
    uint j = 0;
    for(uint i = 0; i < numdirlights; ++i) {
        lightbuf.dirlights[i].z = -1.0f;
        lightbuf.dirlights[i] *= lobjects.dirlights[i];
        lightbuf.dirlights[i].w = lobjects.dirintenses[i];
        lightbuf.dirclrs[i] = lobjects.dirclrs[i];
        ++j;
    }

    // -- remaining directional lights have no intensity
    for(;j < MAX_LIGHTS; ++j) 
        lightbuf.dirlights[j].w = 0.0f;

    // -- create data for the constant buffer pt lights
    j = 0;
    for(uint i = 0; i < numptlights; ++i) {
        lightbuf.ptlights[i] *= lobjects.ptlights[i];
        lightbuf.ptlights[i].w = lobjects.ptintenses[i];
        lightbuf.ptclrs[i] = lobjects.ptclrs[i];
        ++j;
    }

    // -- remaining point lights have no intensity
    for(; j < MAX_LIGHTS; ++j)
        lightbuf.ptlights[j].w = 0.0f;

    // -- create data for the constant buffer spt lights
    j = 0;
    for(uint i = 0; i < lobjects.numsptlights; ++i) {
        lightbuf.cones[i].sptlightdir.z = -1.0f;
        lightbuf.cones[i].sptlightdir.w = lobjects.sptintenses[i];
        lightbuf.cones[i].sptlightpos = lobjects.sptlightspos[i];
        lightbuf.cones[i].sptlightpos.w = lobjects.sptumbras[i];
        lightbuf.cones[i].penumbras.x = lobjects.sptpenums[i];
        lightbuf.cones[i].sptclrs = lobjects.sptclrs[i];
        ++j;
    }

    // -- add the spot lights to the camera list
    for(uint i = 0; i < lobjects.numsptlights; ++i) {
        CCamera lview;
        lview.SetLookAt(Vector4(0.0f, 0.0f, 1.0f));
        lview.SetUp(Vector4(0.0f, 1.0f, 0.0f));
        lview.SetHand(CCamera::eRightHand);
        lview.RotateViewX(lobjects.sptlightsor[i].x);
        lview.RotateViewY(lobjects.sptlightsor[i].y);
        lview.SetPosition(lobjects.sptlightspos[i]);
        cams.Append(lview);
        lviews.Append(&cams.GetLast());
    }

    // -- remaining spt lights have no intensity
    for(; j < MAX_LIGHTS; ++j)
        lightbuf.cones[j].sptlightdir.w = 0.0f;
}

} // namespace NEngine